/**
 * COPYRIGHT. Harry Wu 2011. ALL RIGHTS RESERVED.
 * Project: just
 * Author: Harry Wu <harrywu304@gmail.com>
 * Created On: May 30, 2011 11:21:38 AM
 *
*/ 
package org.justframework.ext.memcached;

import java.io.IOException;
import java.net.URI;
import java.util.concurrent.Future;

import net.spy.memcached.AddrUtil;
import net.spy.memcached.DefaultConnectionFactory;
import net.spy.memcached.FailureMode;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.transcoders.Transcoder;
import net.spy.memcached.transcoders.WhalinTranscoder;

import org.justframework.core.ClientConnector;
import org.justframework.core.Request;
import org.justframework.core.RequestMethod;
import org.justframework.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Memcached client
 *
 */
public class MemcacheClient implements ClientConnector{

	private static Logger logger = LoggerFactory.getLogger(MemcacheClient.class);
	
	/**
	 * whalin方式memcached编码转换器
	 */
	private static Transcoder whalinTranscoder = new WhalinTranscoder();
	
	private Object get(URI uri){
		Object result = null;
		MemcachedClient mcc = null;
		String key = uri.getPath();
		try {
			//初始化memcached客户端
			mcc = getMemcachedClient(uri);
			result = mcc.get(key, whalinTranscoder);
		} catch (Exception ex) {
			logger.error("get key[{}] exception.", key);
		} finally{
			if(mcc != null){
				mcc.shutdown();
			}
		}
		return result;
	}
	
	private Object set(URI uri, Object value){
		Object result = null;
		MemcachedClient mcc = null;
		String key = uri.getPath();
		try {
			//初始化memcached客户端
			mcc = getMemcachedClient(uri);
			Future<Boolean> f = mcc.set(key,1000,value,whalinTranscoder);
			result = f.get();
		} catch (Exception ex) {
			logger.error("get key[{}] exception.", key);
		} finally{
			if(mcc != null){
				mcc.shutdown();
			}
		}
		return result;
	}
	
	private Object delete(URI uri){
		Object result = null;
		MemcachedClient mcc = null;
		String key = uri.getPath();
		try {
			//初始化memcached客户端
			mcc = getMemcachedClient(uri);
			Future<Boolean> f = mcc.delete(key);
			result = f.get();
		} catch (Exception ex) {
			logger.error("get key[{}] exception.", key);
		} finally{
			if(mcc != null){
				mcc.shutdown();
			}
		}
		return result;
	}
	
	private MemcachedClient getMemcachedClient(URI uri) throws IOException{
		MemcachedClient mcc = null;
		//初始化memcached客户端
		mcc = new MemcachedClient(new DefaultConnectionFactory() {
				@Override
				public FailureMode getFailureMode(){
					FailureMode mode = super.getFailureMode();
					return FailureMode.Redistribute;
				}
				
				@Override
				public long getOperationTimeout() { 
					return 3000L; 
				}
			},AddrUtil.getAddresses(uri.getHost()+":"+uri.getPort()));
		return mcc;
	}

	/* (non-Javadoc)
	 * @see org.justframework.core.ClientConnector#rpc(org.justframework.core.Request)
	 */
	public Response rpc(Request request) {
		RequestMethod method = request.getRequestMethod();
		URI uri = request.getUri();
		Object result = null;
		if(RequestMethod.POST == method || RequestMethod.PUT == method){
			Object value = request.getParams().get("value");
			result = set(uri,value);
		} else if(RequestMethod.GET == method){
			result = get(uri);
		} else if(RequestMethod.DELETE == method){
			result = delete(uri);
		}
		
		Response response = null;
		if(result != null){
			response = new Response();
			response.setContent(result);
		}
		return null;
	}
	
}
